package com.gengzp.rpc.core.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.gengzp.rpc.context.RpcRequestContextHolder;
import com.gengzp.rpc.core.RpcCacheCoreFunc;
import com.gengzp.rpc.core.RpcInvocationCoreFunc;
import com.gengzp.rpc.tools.RpcJsonConvertor;
import com.gengzp.rpc.core.RpcRemoteTransactionCoreFunc;
import com.gengzp.rpc.exception.RpcException;
import com.gengzp.rpc.factory.RpcBeanInstanceFactory;
import com.gengzp.rpc.model.remoteTransaction.dto.RemoteTransactionDto;
import com.gengzp.rpc.model.remoteTransaction.req.RpcRollbackRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import static com.gengzp.rpc.constants.RpcCacheKeyConstants.REMOTE_TRANSACTION_CACHE_KEY;
import static com.gengzp.rpc.constants.RpcUriConstants.RPC_PRODUCER_CONTROLLER_URI;
import static com.gengzp.rpc.constants.RpcUriConstants.RPC_PRODUCER_ROLLBACK_METHOD_URI;

/**
 * @ClassName RpcRemoteTransactionCoreFuncImpl
 * @Description rpc框架远程事务核心方法实现类
 * @Author gengzp
 * @Date 2025/8/22 21:48
 */
@Component
public class RpcRemoteTransactionCoreFuncImpl implements RpcRemoteTransactionCoreFunc {

    @Autowired
    private RpcCacheCoreFunc rpcCacheCoreFunc;

    @Autowired
    private RpcBeanInstanceFactory rpcBeanInstanceFactory;

    @Autowired
    private RpcInvocationCoreFunc rpcInvocationCoreFunc;

    @Override
    public void doCommitRemoteTransaction(String serviceName, String interfaceName, Method method, Object[] args) {
        // 1.组装远程事务的缓存key
        String remoteTransactionCacheKey = REMOTE_TRANSACTION_CACHE_KEY +
                RpcRequestContextHolder.getRequestIdentification().getRequestId();

        // 2.取出当前请求id已经提交的事务信息, 如果没有则创建
        List<RemoteTransactionDto> remoteTransactionDtos = new ArrayList<>();
        String currentTransactionCacheStr = rpcCacheCoreFunc.get(remoteTransactionCacheKey);
        if (currentTransactionCacheStr != null && !currentTransactionCacheStr.isBlank()) {
            remoteTransactionDtos = RpcJsonConvertor.convertJsonToGenericObject(currentTransactionCacheStr,
                    new TypeReference<>() {
                    });
        }

        // 3.将当前事务信息加入列表
        RemoteTransactionDto remoteTransactionDto = new RemoteTransactionDto();
        remoteTransactionDto.setServiceName(serviceName);
        remoteTransactionDto.setInterfaceName(interfaceName);
        remoteTransactionDto.setMethodName(method.getName());
        remoteTransactionDto.setArgs(args);
        remoteTransactionDto.setParameterTypes(method.getParameterTypes());
        remoteTransactionDtos.add(remoteTransactionDto);

        // 4.重新保存已提交的事务信息
        rpcCacheCoreFunc.set(remoteTransactionCacheKey, RpcJsonConvertor.convertObjectToJson(remoteTransactionDtos));
    }

    @Override
    public void doExecuteRemoteTransactionRollback() {
        // 1.获取请求id
        String requestId = RpcRequestContextHolder.getRequestIdentification().getRequestId();

        // 2.根据当前请求的 requestId, 查询已提交的事务信息
        List<RemoteTransactionDto> remoteTransactionDtos = new ArrayList<>();
        String committedTransactionCacheStr = rpcCacheCoreFunc.get(REMOTE_TRANSACTION_CACHE_KEY + requestId);
        if (committedTransactionCacheStr != null && !committedTransactionCacheStr.isBlank()) {
            remoteTransactionDtos = RpcJsonConvertor.convertJsonToGenericObject(committedTransactionCacheStr,
                    new TypeReference<>() {
                    });
        }
        if (remoteTransactionDtos.isEmpty()) {
            return;
        }

        // 4.循环处理每一条事务的回滚逻辑
        for (RemoteTransactionDto remoteTransaction : remoteTransactionDtos) {

            // (1).组装远程事务回滚调用的参数信息
            RpcRollbackRequest rollbackReq = new RpcRollbackRequest();
            rollbackReq.setRequestId(requestId);
            rollbackReq.setInterfaceName(remoteTransaction.getInterfaceName());
            rollbackReq.setMethodName(remoteTransaction.getMethodName());
            rollbackReq.setArgs(remoteTransaction.getArgs());
            rollbackReq.setParameterTypes(remoteTransaction.getParameterTypes());

            // (2).获取对应服务的请求url
            List<String> addresses = rpcBeanInstanceFactory.getRpcRemoteServiceRouteStrategy()
                    .getServiceInstanceAddressByServiceName(remoteTransaction.getServiceName());
            if (addresses == null || addresses.isEmpty()) {
                throw RpcException.get(String.format("未找到 %s 的在线服务实例, 无法执行远程事务回滚逻辑", remoteTransaction.getServiceName()));
            }

            // (3).执行回滚逻辑调用
            rpcBeanInstanceFactory.getRpcRemoteTransactionRollbackProcessor().doRollbackRemoteTransaction(
                    // ①.拼装完整的请求url
                    addresses.get(ThreadLocalRandom.current().nextInt(addresses.size())) +
                            RPC_PRODUCER_CONTROLLER_URI + RPC_PRODUCER_ROLLBACK_METHOD_URI,
                    // ②.获取远程调用请求头
                    rpcInvocationCoreFunc.getCustomRemoteCallRequestHeader(),
                    // ③.远程回滚调用请求参数
                    rollbackReq);
        }
    }

    @Override
    public void doClearRemoteTransactionCache() {
        rpcCacheCoreFunc.del(REMOTE_TRANSACTION_CACHE_KEY + RpcRequestContextHolder.getRequestIdentification().getRequestId());
    }

}
